/*
 * TwittavaWindow.java
 *
 * Created on April 17, 2007, 2:28 PM
 */

package org.voidness.twittava.gui;

import java.awt.Color;
import java.awt.SystemTray;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.util.Collection;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.SwingWorker;
import javax.swing.Timer;
import org.voidness.twittava.Application;
import org.voidness.twittava.config.ConfigurationManager;
import org.voidness.twittava.domain.Status;
import org.voidness.twittava.gui.glass.PropertiesGlassPanel;
import org.voidness.twittava.gui.glass.WaitingGlassPanel;

/**
 *
 * @author  void
 */
public class TwittavaWindow extends JFrame {
    
    private WaitingGlassPanel glass = null;
    private Application app = null;
    private Timer refreshTimer = null;
    private int currentTime;
    private static final int REFRESH_TIME = 60; // seconds
    private boolean setup = false;
    
    /** Creates new form TwittavaWindow */
    public TwittavaWindow() {
        initComponents();
        
        // Setup some more window parameters
        this.setSize(500, 500);
        this.setTitle("Twittava");
        this.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
        
        setupApplication();
    }
    
    public void getOut() {
        // Save last window location to the properties and exit
        ConfigurationManager.getInstance().setProperty("windowLocationX", this.getLocation().x+"");
        ConfigurationManager.getInstance().setProperty("windowLocationY", this.getLocation().y+"");
        ConfigurationManager.getInstance().save();
        System.exit(0);
    }
    
    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
    private void initComponents() {
        jScrollPane1 = new javax.swing.JScrollPane();
        statusesPanel = new javax.swing.JPanel();
        jPanel1 = new javax.swing.JPanel();
        postField = new javax.swing.JTextField();
        postButton = new javax.swing.JButton();
        propertiesButton = new javax.swing.JButton();
        refreshButton = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setResizable(false);
        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowClosing(java.awt.event.WindowEvent evt) {
                formWindowClosing(evt);
            }
        });

        statusesPanel.setLayout(new javax.swing.BoxLayout(statusesPanel, javax.swing.BoxLayout.Y_AXIS));

        jScrollPane1.setViewportView(statusesPanel);

        getContentPane().add(jScrollPane1, java.awt.BorderLayout.CENTER);

        jPanel1.setLayout(new java.awt.BorderLayout());

        postField.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyPressed(java.awt.event.KeyEvent evt) {
                postFieldKeyPressed(evt);
            }
        });

        jPanel1.add(postField, java.awt.BorderLayout.CENTER);

        postButton.setText("Send!");
        postButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                postButtonActionPerformed(evt);
            }
        });

        jPanel1.add(postButton, java.awt.BorderLayout.EAST);

        propertiesButton.setText("!");
        propertiesButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                propertiesButtonActionPerformed(evt);
            }
        });

        jPanel1.add(propertiesButton, java.awt.BorderLayout.WEST);

        getContentPane().add(jPanel1, java.awt.BorderLayout.SOUTH);

        refreshButton.setText("Refreshing in x seconds. Click here to force.");
        refreshButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                refreshButtonActionPerformed(evt);
            }
        });

        getContentPane().add(refreshButton, java.awt.BorderLayout.NORTH);

        pack();
    }// </editor-fold>//GEN-END:initComponents
    
    private void postFieldKeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_postFieldKeyPressed
        if (evt.getKeyCode() == KeyEvent.VK_ENTER) {
            postButtonActionPerformed(null);
        }
    }//GEN-LAST:event_postFieldKeyPressed
    
    private void formWindowClosing(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowClosing
        // If the system tray is supported just hide the window,
        // else exit the application
        if (SystemTray.isSupported()) {
            this.setVisible(false);
        } else {
            getOut();
        }
    }//GEN-LAST:event_formWindowClosing
    
    private void propertiesButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_propertiesButtonActionPerformed
        PropertiesGlassPanel propertiesGlass = new PropertiesGlassPanel(this);
        propertiesGlass.setBackground(new Color(211, 233, 255));
        setGlassPane(propertiesGlass);
        propertiesGlass.setVisible(true);
    }//GEN-LAST:event_propertiesButtonActionPerformed
    
    private void refreshButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_refreshButtonActionPerformed
        currentTime = 0;
        updateTwitts();
    }//GEN-LAST:event_refreshButtonActionPerformed
    
    private void postButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_postButtonActionPerformed
        if (!postField.getText().equals("")) {
            glass.setVisible(true);
            new SwingWorker<Status, Object>() {
                Status newStatus = null;
                
                protected Status doInBackground() throws Exception {
                    try {
                        newStatus = app.postStatus(postField.getText());
                    } catch (Exception exc) {
                        exc.printStackTrace();
                        JOptionPane.showMessageDialog(TwittavaWindow.this, "The following problem occured while posting status: " + exc.getMessage(), "Problem occured!", JOptionPane.ERROR_MESSAGE);
                    } finally {
                        glass.setVisible(false);
                    }
                    return null;
                }
                
                protected void done() {
                    glass.setVisible(false);
                    if (newStatus != null) {
                        // Add the new status to the panel
                        statusesPanel.add(new StatusPanel(newStatus, 0, statusesPanel.getComponentCount()), 0);
                        // Clear the text field
                        postField.setText("");
                    } else {
                        // TODO: Warn the user or something :)
                    }
                }
            }.execute();
        } else {
            System.out.println("Not sending. Reason: empty status.");
        }
    }//GEN-LAST:event_postButtonActionPerformed
    
    public void setupGlassPane() {
        glass = new WaitingGlassPanel();
        glass.setBackground(new Color(211, 233, 255, 220));
        setGlassPane(glass);
        glass.setVisible(false);
    }
    
    private void updateTwitts() {
        glass.setVisible(true);
        new SwingWorker<Object, Object>() {
            protected Object doInBackground() throws Exception {
                // Get them all
                try {
                    Collection<Status> statuses = app.getFriendsTimeline();
                    System.out.println("Got " + statuses.size() + " status posts from the server.");
                    
                    statusesPanel.removeAll();
                    int index = 0;
                    for (Status status : statuses) {
                        statusesPanel.add(new StatusPanel(status, index++, statuses.size()));
                    }
                } catch (Exception exc) {
                    exc.printStackTrace();
                    JOptionPane.showMessageDialog(TwittavaWindow.this, "The following problem occured while getting friends timeline: " + exc.getMessage(), "Problem occured!", JOptionPane.ERROR_MESSAGE);
                } finally{
                    glass.setVisible(false);
                }
                
                return null;
            }
        }.execute();
    }
    
    private void startRefreshTimer() {
        currentTime = 0;
        refreshTimer = new Timer(1000, new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                currentTime++;
                refreshButton.setText("Refreshing in " + (REFRESH_TIME - currentTime) + " seconds. Click here to force.");
                if (currentTime >= REFRESH_TIME) {
                    updateTwitts();
                    currentTime = 0;
                }
            }
        });
        refreshTimer.start();
    }
    
    public void setupApplication() {
        if (setup) {
            return;
        }
        
        // Check whether we have connection details available
        String username = ConfigurationManager.getInstance().getProperty("username");
        String password = ConfigurationManager.getInstance().getProperty("password");
        
        // If we don't then we must set them
        if (username == null || password == null ||
                username.trim().equals("") || password.trim().equals("")) {
            propertiesButtonActionPerformed(null);
        } else {
            // Setup application and glasspane
            app = new Application();
            setupGlassPane();
            
            // Update twit list and start refresh timer
            updateTwitts();
            startRefreshTimer();
            
            setup = true;
        }
        
        // Check if we have a location stored
        String locationX = ConfigurationManager.getInstance().getProperty("windowLocationX");
        String locationY = ConfigurationManager.getInstance().getProperty("windowLocationY");
        if (locationX != null && locationY != null) {
            try {
                int x = Integer.parseInt(locationX);
                int y = Integer.parseInt(locationY);
                this.setLocation(x, y);
            } catch (Exception exc) {
                // Oops, could not parse values
            }
        }
    }
    
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JPanel jPanel1;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JButton postButton;
    private javax.swing.JTextField postField;
    private javax.swing.JButton propertiesButton;
    private javax.swing.JButton refreshButton;
    private javax.swing.JPanel statusesPanel;
    // End of variables declaration//GEN-END:variables
    
}
